home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 October
/
EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso
/
Aminet
/
dev
/
asm
/
Asm_Course2.lha
/
Teil27.TXT
< prev
next >
Wrap
Text File
|
1992-09-02
|
12KB
|
321 lines
A S S E M B L E R - K U R S (c) Jeff Kandle 1990
27.Teil...
Hat mal wieder etwas laenger gedauert, aber ich habe im moment sehr viel zu
tun. Unter anderem muss ich mich um ein Netzteil fuer meine Festplatte
kuemmern die ich mir gekauft habe. Das wird auch noch etwas dauern, und
sobald ich alles fuer die Platte habe muss ich sie mir ja auch noch
einrichten und mich damit bekannt machen. Also wenn die Teile jetzt
Zeitlich ein bisschen mehr auseinander liegen, dann denkt nicht ich haette
euch vergessen, es ist einfach nur die Platte.
Aber weiter gehts...
Das einfache setzen eines Bobs duerfte jetzt ja kein Problem mehr sein,
oder ?
Geben wir uns mal an eine Routine die aus einem Wort die X und Y
Koordinaten errechnet und die Werte fuer den Blitter setzt.
Allerdings treten da ein paar wichtige sachen auf die man beachten muss.
Aber fangen wir mal Theoretisch an. Um das Programm einfach zu halten
arbeiten wir nur mit PAL-Koordinaten. Das heisst das wir zwar einen
Overscan Screen haben, aber nur Koordinaten von 0 bis 255 erlauben.
Ich gehe diese Theoretischen durchlauf einer solchen Routine mit einem
Beispielwert durch. Das erleichtert die sache.
Der Beispielwert ist $5167, also Y = $51 und X = $67.
Die Werte fuer den Bildschirm sind.
Bitplanes bei $60000,$6002c,$60058 (Verschachtelt)
Bytes pro Zeile = 44($2c)
Rechnen wir erstmal den Y-Wert aus...
Dazu muessen wir erstmal den anderen Krempel loswerden der noch in dem
Kontrollwort steht. Das machen wir indem wir es durch $100 Dividieren. Dann
steht nur noch die $0051 da.
Also Zeile $51....Da muessten wir normalerweise zum Anfang der Plane nur
$51 * $2c Addieren. Da wir aber drei verschachtelte Planes haben, muss man
den ganzen Krempel noch mal drei nehmen. Damit wir uns eine Multiplikation
zu ersparen nehmen wir die Zeilenzahl direkt mal $84 (3 * $2c).
Bei Zeile $51 muesste dann $51 * $84 + $60000 gerechnet werden.
Da kommt nach Adam`s Riesen $629c4 bei raus. Das ist also der Zeilenanfang
an dem der Bobs steht.
Gehen wir jetzt weiter zur Komplizierteren Routine. Holen wir uns erneut
das Kontrollwort. Mit der Logischen Funktion AND koennen wir den Oberen
Teil ausmaskieren. Bleibt noch die $67, die die X Koordinate in Pixeln
angibt. Da wir aber immer nur 15 Pixel verschieben koennen muessen wir
erstmal mit Hardscrolling so nah wie moeglich an den Punkt rankommen an dem
der Bob dann hinterher steht. Also brauchen wir erstmal die 6. Teilen wir
den Krempel durch $10. Jetzt steht die $6 im Wort. Da wir nicht Byteweise
sondern Wortweise arbeiten, muessen wir die 6 noch verdoppeln. Dazu
multiplizieren wir es nicht, sondern Addieren das Register zu sich selbst
dazu. Denn die Multiplikation des MC 68000 sind eine sehr langsame sache.
Nachdem wir es verdoppelt haben, koennen wir es zu der Adresse der Zeile
dazuaddieren. Dann stehen wir schon sehr nah am Ziel.
Jetzt muessen wir noch den Wert fuer das Softscrollen errechnen..
Dazu maskieren wir alles ausser den Softwert mit AND aus. Nehmen den * $100
um ihn in das Highbyte des hinteren Wortes zu kriegen, und Addieren dazu
einfach den Rest des BLTCON0 Registers dazu.
Diese Routine macht das eben besprochene. Am Ende der Routine steht in A0
die Adresse an der der Bob dargestellt wird, und in D0 das Komplette Word
fuer das BLTCON0 Register.
; Beim Aufruf der Routine muss das Kontrollwort schon feststehen und
; in D7 stehen.
CoordCalc:
Move.l d7,d1 ; Kontrollwort nach D1
And.l #$ff00,d1 ; Alles ausser Y-Werte aus-
; maskieren !
Divs #$100,d1 ; Nach unten schieben
Muls #$84,d1 ; Wert auf dem Screen ermitteln
Add.l #$60000,d1 ; Plus PlayfieldBase
Move.l d1,a0 ; Nach A0 setzen.
Move.l d7,d1 ; Erneut holen !
And.l #$00f0,d1 ; Unwichtiges ausmaskieren
Lsr.l #3,d1 ; Ersetzt Divs $10 und verdoppeln
Add.l d1,a0
Move.l d7,d1 ; !!!
And.l #$f,d1 ; Ausmaskieren !
Swap d1
Lsr.l #4,d1
Move.w #%0000100111110000,d0 ; BLTCON0-Wert ohne Scrollwert
; nach d0
Add.w d1,d0 ; D1 zu D0 addiert ergibt BLTCON0
Clr.l d1 ; Werte nur in D0 und A0 lassen
Clr.l d7
Bsr.l Set_bob ; Bob setzen.
Rts
So diese koennt ihr direkt hinter die Set_Bob-Routine setzen. Da diese
Routine vor der Set_bob aufgerufen werden muss, muesst ihr in dem oberen
Teil des Listings aus dem Bsr.l Set_Bob ein Bsr.l Coordcalc machen.
Davor setzt ihr zum Probieren die Zeile
Move.l #$5167,d7
Damit es schonmal laeuft.
Dann muesst ihr noch die Set_Bob Routine aendern, das nicht mehr die festen
Werte geschrieben werden, sondern D0 nach BLTCON0 und A0 nach BLTDPT
geschrieben wird, das muesstet ihr finden.
Als letztes koennt ihr noch in der Clearschleife aus der -1 eine 0 machen,
damit der Screen Schwarz wird und man die Raender links und rechts von Bob
sehen, obwohl es ja auch ganz Interressant ist sie zu sehen.
Um diesen Bob auf dem Screen rumflitzen zu lassen, muessen wir eigentlich
nur noch eine Routine schreiben die der Coordcalc-Routine laufend neue
Koordinaten uebergibt. Das sollte dann jeden Bildschirm aufbau passieren.
Also muessen wir die abfrage der Bildschirmposition einbauen, die Tabelle
mit den Positionen und die Routine die die Koordinaten uebergibt und die
Tabelle rotiert.
Allerdings fehlt dann noch etwas...Naemlich eine Routine die den alten Bob
loescht damit die Reste nicht auf dem Bildschirm bleiben. Das ist zwar ein
netter Effekt, aber auch nicht unbedingt das was wir wollen.
So hier erstmal das Prograemmchen. Ich habe keine Koordinatentabelle
benutzt weil sie Platz wegnimmt, und ich ausserdem keine lust habe mir die
Finger an so einer Tabelle wund zu schreiben. Das Position des Bobs wird
durch einen ADD befehl veraendert.
Start:
Execbase= 4
Openlibrary= -408
Vposr= $dff004
Forbid= -30-102
Permit= -30-108
Bltafwm= $dff044
Bltalwm= $dff046
Bltcon0= $dff040
Bltcon1= $dff042
Bltamod= $dff064
Bltdmod= $dff066
Bltapt= $dff050
Bltdpt= $dff054
Dmacon= $dff096
Intena= $dff09a
Dmaconr= $dff002
Bltsize= $dff058
Cop1lc= $dff080
Move.w #$0020,Dmacon
Move.w #$4000,Intena
Move.l Execbase.w,a6
Jsr Forbid(a6)
Move.l #$60000,a0
Move.l #$9588/4,d0
Clearloop:
Move.l #0,(a0)+
Dbf d0,Clearloop
Bsr.l Makecl
Wait: Move.l Vposr,d0
And.l #$1ff00,d0
Cmp.l #$1000,d0
Bne.s Wait
Bsr.l Kill_old
Bsr.l Get_Pos
Btst #6,$bfe001
Bne.s Wait
Move.l Execbase.w,a6
Jsr Permit(a6)
Lea Gfxname(pc),a1
Jsr Openlibrary(a6)
Move.l d0,a6
Move.w #$83e0,Dmacon
Move.w #$c000,Intena
Move.l 38(a6),Cop1lc
Moveq #0,d0
Rts
Makecl:
Lea $05f000,a0
Move.l a0,$dff080
Move.l #$00e00006,(a0)+
Move.l #$00e20000,(a0)+
Move.l #$00e40006,(a0)+
Move.l #$00e6002c,(a0)+
Move.l #$00e80006,(a0)+
Move.l #$00ea0058,(a0)+
Move.l #$008e1a64,(a0)+
Move.l #$009039d1,(a0)+
Move.l #$00920030,(a0)+
Move.l #$009400d8,(a0)+
Move.l #$01003200,(a0)+
Move.l #$01080058,(a0)+
Move.l #$010a0058,(a0)+
;----------------------------------------------
Move.l #$01800000,(a0)+
Move.l #$0182071d,(a0)+
Move.l #$0184088e,(a0)+
Move.l #$0186044f,(a0)+
Move.l #$0188000f,(a0)+
Move.l #$018a000c,(a0)+
Move.l #$018c0008,(a0)+
Move.l #$018e0004,(a0)+
;----------------------------------------------
Move.l #$fffffffe,(a0)+
Rts
Waitblit:
Btst #6,Dmaconr
Bne.s Waitblit
Rts
Set_bob:
Bsr.s Waitblit
Move.w #$ffff,Bltafwm
Move.w #$ffff,Bltalwm
Move.w d0,Bltcon0
Move.w #0,Bltamod ; Quellmodulo = 0 (rawblit)
Move.w #38,Bltdmod ; Zielmodulo = 38 (planes = $2c)
Move.l #$5e000,Bltapt ; Quelladr.
Move.l a0,Bltdpt ; Zieladr.
Move.w #96*64+3,Bltsize ; Bltsize und Start
Rts
; Beim Aufruf der Routine muss das Kontrollwort schon feststehen und
; in D7 stehen.
CoordCalc:
Move.l d7,d1 ; Kontrollwort nach D1
And.l #$ff00,d1 ; Alles ausser Y-Werte aus-
; maskieren !
Divs #$100,d1 ; Nach unten schieben
Muls #$84,d1 ; Wert auf dem Screen ermitteln
Add.l #$60000,d1 ; Plus PlayfieldBase
Move.l d1,a0 ; Nach A0 setzen.
Move.l d7,d1 ; Erneut holen !
And.l #$00f0,d1 ; Unwichtiges ausmaskieren
Lsr.l #3,d1 ; Ersetzt Divs $10 und verdoppeln
Add.l d1,a0
Move.l d7,d1 ; !!!
And.l #$f,d1 ; Ausmaskieren !
Swap d1
Lsr.l #4,d1
Move.w #%0000100111110000,d0 ; BLTCON0-Wert ohne Scrollwert
; nach d0
Add.w d1,d0 ; D1 zu D0 addiert ergibt BLTCON0
Clr.l d1 ; Werte nur in D0 und A0 lassen
Clr.l d7
Bsr.l Set_bob ; Bob setzen.
Move.l a0,Old_Pos ; Position fuer loeschroutine
; merken !
Rts
Kill_Old:
Bsr.l Waitblit
Move.l #$-1,Bltalwm
Move.w #38,Bltdmod
Move.w #%0000000100000000,Bltcon0
Move.l Old_Pos,Bltdpt
Move.w #96*64+3,Bltsize
Rts
Get_Pos:
Move.w Position,d7
Add.w #$101,Position
Bsr.l Coordcalc
Rts
Old_Pos: Dc.l $60000
Position: Dc.w 0
Gfxname: dc.b "graphics.library",0
>Extern "bob.raw",$5e000
Wichtig ist allerdings eines.
Da ich die Kill_Old Routine vor der Get_Pos Routine aufrufe, und sie die
Koordinaten erst beim Ersten Aufruf von Get_Pos kriegt muesst ihr das
reservierte Langwort Old_pos mit irgendeiner Adresse fuellen.
Ich hatte naemlich nur geschrieben
Old_pos: Dc.l 0
Und mein Amiga stuerzte jedesmal nach dem Druck auf die Maustaste ab.
Was war passiert:
Beim ersten Aufruf der Kill_Old Routine hat der Blitter als Destination
fuer seine Loeschaktion die 0 als Adresse gekriegt. Und da bei 0 und $4
sehr wichtige Daten liegen war das nicht so gut. Das Programm lief ohne
Probs weiter. Sobald ich aber das Programm beenden wollte und auf die
Maustaste drueckte stuerzte er ab. Ganz klar - er holte sich die Execbase
nach A6 und sprang Openlibrary an. Da aber nicht mehr die Execbase sondern
Irgendetwas in $4 stand, ging er daran zu grunde.
Solche sachen bringen mich dann immer um denn Verstand. Ich sitze dann
immer wie Apathisch vor der Kiste. Schreibe nach und nach alle Routinen neu
und nicht passiert.
Beim Essen ist es mir dann eingefallen was das schief gelaufen ist.
So kanns gehen...
Da ich wiegesagt keine Tabelle fuer die position dabei gesetzt habe,
solltet ihr das mal selber versuchen. Es duerfte allerdings kein Problem
fuer euch sein. Denn ihr habt das ja schon mehrmals gemacht.
Ihr koennt auch mal versuchen die Routine auf mehrere Bobs um zu schreiben.
Dabei werdet ihr dann auf eine Sache stossen die dem Thema Bobs einen sehr
komplizierten Touch geben. Und wir werden uns damit sehr stark auseinander
setzen muessen.
Naja, ich will euch nicht den Mut nehmen....
Schoenen Tag noch
Jeff Kandle